import { Injectable } from '@nestjs/common';
import { ChargeStrategy } from 'src/entities/ChargeStrategy';
import { ChargeStrategyModelService } from 'src/model/charge-strategy-model/charge-strategy-model.service';
import { getTime } from 'src/utils';
import { FindConditions, Like } from 'typeorm';
import ListDto, { AddDto, EditDto } from './dto';

@Injectable()
export class ChargeStrategyService {
    constructor(
        private model:ChargeStrategyModelService
    ){}

    async list(dto:ListDto, merchantId:number) {
        let where:FindConditions<ChargeStrategy> = {merchantId}

        if(dto.strategyName) {
            where.strategyName = Like(`%${dto.strategyName}%`)
        }

        let result:PaginationResult<ChargeStrategy> = {
            total : 0,
            rows : []
        }
        result.total = await this.model.count(where)
        if(result.total > 0) {
            result.rows = await this.model.pagination(dto.pageNo, dto.pageSize, where, null, {strategyId : 'DESC'})
        }

        return result
    }

    async queryStrategyName(name:string) {
        let rows = await this.model.find({strategyName : Like(name + '%')}, ['strategyId', 'strategyName'], 0, 10, {strategyId : 'DESC'})
        return rows
    }

    async add(dto:AddDto, merchantId:number) {
        let res = await this.model.isExistsByWhere({merchantId, strategyName : dto.strategyName})
        if(res) {
            throw new Error('已存在相同的策略名')
        }

        let data:{[key in keyof ChargeStrategy]? : ChargeStrategy[key]} = {...dto, merchantId}

        data.integrated = this.integrateStrategy(dto)
    
        data.createTime = getTime()

        try {
            
            const res = await this.model.insert(data)

            return res > 0

        } catch (error) {
            
        }

        return false
    }

    async getEditData(strategyId:number, merchantId:number) {
        const strategy:ChargeStrategy = await this.model.findOne({strategyId})

        return (strategy && strategy.merchantId == merchantId) ? strategy : null
    }

    async edit(strategyId:number, merchantId:number, dto:EditDto) {
        let data:{[key in keyof ChargeStrategy]? : ChargeStrategy[key]} = {}
        if(Object.keys(dto).length == 0) return true
 
        const strategy = await this.model.findOne({strategyId : strategyId})

        if(!strategy) return true

        for(let k in dto) {
            if(JSON.stringify(strategy[k]) != JSON.stringify(dto[k])) {
                data[k] = dto[k]
            }
        }

        if(Object.keys(data).length == 0) return true

        if(data.strategyName && (await this.model.isExistsByWhere({merchantId, strategyName : dto.strategyName}))) {
            throw new Error('已存在相同的策略名')
        }

        data.integrated = this.integrateStrategy(strategy)

        data.updateTime = getTime()

        try {
            let affectedRows = await this.model.update({strategyId : strategyId}, data)
            if(affectedRows) {
                return true
            }
        } catch (error) {
            
        }

        return false

    }

    integrateStrategy(strategy:ChargeStrategy) {
        let data:any = {
            autoStopFlag : Number(strategy.fullStop),
            emergChargeFlag : Number(strategy.emergCharge),
            emergNum : strategy.emergCount || 0,
            emergEnergy : (strategy.emergEnergy || 0) * 1000,
            consumeMode : strategy.strategyType,
            minUnit : strategy.strategyType == 3 ? 0 : (strategy.strategyType == 1 ? strategy.settleUnit : strategy.settleUnit * 1000),
            preFee : Number(strategy.cardChargeAmount) * 100,
            price : strategy.strategyType == 2 ? Number(strategy.unitPrice) * 100 : 0,
            fullPower : (strategy.fullPower || 25) * 100,
            fullDelay : strategy.fullDelay || 10,
            plugOffDly : strategy.plugOffDly || 60,
            occupyPrice : strategy.occupyPrice || 0,
            freeOccupyTime : strategy.freeOccupyTime || 0
        }

        let rules = []
        for(let i = 0; i < 4; i ++) {
            const rule = strategy.rules[i]
            if(rule) {
                rules.push(rule)
            }else {
                rules.push(rules[i - 1])
            }
        }

        rules.forEach((rule, index) => {
            data[`stage${(index + 1)}Price`] = rule.a * 100
            data[`pwrClass${(index + 1)}`] = rule.w * 100
        })

        return data
    }
}
